package com.imu.purse.modules.sms;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.imu.common.utils.PhoneUtil;
import com.imu.constant.Constant;
import com.imu.purse.modules.sms.config.ConfigUtil;
import com.imu.purse.modules.sms.entity.SmsLogEntity;
import com.imu.purse.modules.sms.service.SmsLogService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class SMSAliMessage {

    private final static String name = ConfigUtil.getValue("sms.aliyun.product.name", "核控科技");
    //key
    private final static String accessKeyId = ConfigUtil.getValue("aliyun.product.accessKeyId", "LTAIbY6nmqqOZpim");

    //密钥
    private final static String accessKeySecret = ConfigUtil.getValue("aliyun.product.accessKeySecret", "NAVaJEzigXqTwvos4nZlXYoTHAdGEy");

    //api
    private final static String smsapi = ConfigUtil.getValue("aliyun.product.smsapi", "Dysmsapi");

    //域名
    private final static String domain = ConfigUtil.getValue("aliyun.product.domain", "dysmsapi.aliyuncs.com");

    private final static String region = ConfigUtil.getValue("aliyun.product.profile","cn-hangzhou");

    private final static String eFirst = ConfigUtil.getValue("aliyun.product.endpoint.first","cn-hangzhou");

    private final static String eSecond = ConfigUtil.getValue("aliyun.product.endpoint.second","cn-hangzhou");
    //模板
    private final static String template = ConfigUtil.getValue("aliyun.product.template", "您的短信验证码是:{code},有效期为30分钟,请尽快使用,每天最多可发送10条。");
    private final static String templateCode = ConfigUtil.getValue("aliyun.product.template.code", "SMS_133266490");
    // 日志记录
    private static final Logger logger = LoggerFactory.getLogger(SendSMS.class);
    //imu应用异常模板
    private static final String bitTemplate = ConfigUtil.getValue("bitcoin.error.template","IMU应用程序可能异常，请及时查看!");
    private static final String bitTemplateCode = ConfigUtil.getValue("bitcoin.error.template.code","SMS_133261620");

    //港澳台
    private final static String twTemplate = ConfigUtil.getValue("sms.aliyun.product.tw.template","您的簡訊驗證碼是：{name}，有效期為5分鐘，請儘快使用，每天最多可發送10條。");
    private final static String twTemplateCode = ConfigUtil.getValue("sms.aliyun.product.tw.code","SMS_136392990");

    //国外
    private final static String abroadName = ConfigUtil.getValue("sms.aliyun.product.abroad.name","IMUInternat");
    private final static String aboradTemplate = ConfigUtil.getValue("sms.aliyun.product.abroad.template","Your SMS verification code is: {name}, valid for 5 minutes, please use as soon as possible.");
    private final static String aboradTemplateCode = ConfigUtil.getValue("sms.aliyun.product.abroad.code","SMS_136393015");

    @Autowired
    private SMSCache cache;

    @Autowired
    private SmsLogService service;

    @Value("${spring.profiles.active}")
    private String active;

    private IAcsClient initClient() throws ClientException{
        IClientProfile profile = DefaultProfile.getProfile(region, accessKeyId,
                accessKeySecret);
        DefaultProfile.addEndpoint(eFirst,eSecond, smsapi, domain);
        IAcsClient client = new DefaultAcsClient(profile);

        return client;
    }

    private SendSmsRequest initRequest(String phone,String code){
        //组装请求对象
        SendSmsRequest request = new SendSmsRequest();
        //使用post提交
        request.setMethod(MethodType.POST);
        //必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,
        // 批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式；
        // 发送国际/港澳台消息时，接收号码格式为00+国际区号+号码，如“0085200000000”
        request.setPhoneNumbers(phone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(name);
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(templateCode);
        if(PhoneUtil.isTwPhone(phone)){//港澳台手机号码
            request.setTemplateCode(twTemplateCode);
            request.setPhoneNumbers("00" + phone);
        }else if(!PhoneUtil.isCPhone(phone)){//其他都认为是国内号码
            request.setSignName(abroadName);
            request.setTemplateCode(aboradTemplateCode);
        }

        request.setTemplateParam("{\"code\": \"" + code + "\"}");

        return request;
    }
    public void send(SMSMessage message)
    {
        if(null == message)
        {
            logger.info("参数为空.....");
            return;
        }
        String phone = message.getPhone();
        String code = message.getAuthcode();
        SMSMessage.Type type = message.getType();

        SmsLogEntity entity = null;
        try
        {
            entity = new SmsLogEntity();
            entity.setCode(code);
            entity.setPhone(phone);
            entity.setType(type.getType());
            entity.setTimeCreate(new Date());
            entity.setContent(StringUtils.replace(template,"{name}" ,code));
            if(null != active && !active.equals("pro")) {
                //保存到缓存
                cache.saveCode(type.getType(), phone, Constant.DEF_CODE);
                entity.setCode(Constant.DEF_CODE);
                entity.setState(Constant.SUC);
                //保存短信日志记录
                service.save(entity);
                return;
            }
            IAcsClient client = initClient();
            //初始化请求
            SendSmsRequest request = initRequest(phone,code);

            //请求失败这里会抛ClientException异常
            SendSmsResponse response = client.getAcsResponse(request);
            if(response != null && Constant.OK.equalsIgnoreCase(response.getCode())){
                entity.setState(Constant.SUC);
                //删除该之前的缓存
                cache.delCode(type.getType(),phone);
                //保存到缓存
                cache.saveCode(type.getType(),phone,code);

            }else {
                entity.setState(Constant.FAI);
                entity.setDesc(Constant.FAIL);
                logger.error("SMS send failed : " + response.getMessage());
            }
        }
        catch (ClientException e)
        {
            entity.setState(Constant.FAI);
            entity.setDesc(e.getMessage());
            logger.error("SMS send failed:" + e.toString());
        }

        if(null != entity) service.save(entity); //保存短信日志记录
    }

    public void sendRemind(String type,String...phones){
        if(phones == null || phones.length == 0){
            logger.info("phones is empty");
            return;
        }
        String content = null;
        SmsLogEntity entity = null;
        for(String phone : phones){
            content = cache.findRemindData(phone,type);
            if(StringUtils.isEmpty(content)){//代表缓存没有数据，则需要重新发送
                try{
                    entity = new SmsLogEntity();
                    entity.setPhone(phone);
                    entity.setType(type);
                    entity.setTimeCreate(new Date());
                    entity.setContent(bitTemplate);
                    entity.setState(Constant.SUC);
                    //推送短信
                    IAcsClient client = initClient();
                    //组装请求对象
                    SendSmsRequest request = new SendSmsRequest();
                    //使用post提交
                    request.setMethod(MethodType.POST);
                    //必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,
                    // 批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式；
                    // 发送国际/港澳台消息时，接收号码格式为00+国际区号+号码，如“0085200000000”
                    request.setPhoneNumbers(phone);
                    //必填:短信签名-可在短信控制台中找到
                    request.setSignName(name);
                    //必填:短信模板-可在短信控制台中找到
                    request.setTemplateCode(bitTemplateCode);
                    //请求失败这里会抛ClientException异常
                    SendSmsResponse response = client.getAcsResponse(request);
                    if(response != null && Constant.OK.equalsIgnoreCase(response.getCode())){
                        entity.setState(Constant.SUC);
                        //保存到缓存
                        cache.saveRemindData(phone,type,bitTemplate);
                    }else {
                        entity.setState(Constant.FAI);
                        entity.setDesc(Constant.FAIL);
                        logger.error("SMS send failed:" + response.getMessage());
                    }
                }catch (ClientException e){
                    entity.setState(Constant.FAI);
                    entity.setDesc(e.getMessage());
                    logger.error("SMS send failed:" + e.toString());
                }
                //保存短信日志记录
                service.save(entity);
            }
        }
    }
}
